package com.sinosoft.antiques.service;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.imageio.ImageIO;

import com.sinosoft.antiques.common.ConfigReader;
import com.sinosoft.antiques.util.StringUtil;
import com.sinosoft.commontools.annotated.TransAnnotation;
import com.sinosoft.commontools.record.Record;
import com.sinosoft.dbtools.operate.IDBActor;

public class ImportThread extends BasicService implements Runnable {
	public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
	public static SimpleDateFormat timeFormat = new SimpleDateFormat(
			"yyyyMMddHHmmss");
	private volatile static ImportThread importThread;
	private static String importfilepath = "";
	private static String importlogpath = "";
	private static String sysfilepath = "";
	private static List<String> filelist = new ArrayList<String>();

	private ImportThread() {
	}

	public static ImportThread getSingleton() {
		if (importThread == null) {
			synchronized (ImportThread.class) {
				if (importThread == null) {
					importfilepath = ConfigReader.getValue("importfilepath");
					importlogpath = ConfigReader.getValue("importlogpath");
					sysfilepath = ConfigReader.getValue("sysfilepath");
					importThread = new ImportThread();
					importThread.run();
				}
			}
		}
		return importThread;
	}

	private static String currentFiletime = "";
	private static FileOutputStream successfos = null;
	private static FileOutputStream failedfos = null;
	private static String failedfilepath = "";

	@Override
	public void run() {
		while (true) {
			System.out.println("执行任务：" + new Date());
			List<Record> list = getTask();
			if (list!=null&&list.size()>0) {
				System.out.println("任务数量：" + list.size());
				for(Record data:list){
					int taskid = data.getIntValue("id");
					String userid = data.getStrValue("userid");
					String filepath = data.getStrValue("filepath");
					addYxList_mass(taskid,userid,filepath);
				}
			}
			// 每次执行之后睡眠1分钟
			try {
				Thread.sleep(1000 *60);// 10*60*
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	@TransAnnotation(isTrans = true)
	private Record addYxList_mass(int taskid, String userid, String yxpath) {
		Record record = new Record();Record data = new Record();
		data.add("userid", userid);
		if(StringUtil.isNoEmpty(yxpath)){
			String firstchar = yxpath.substring(0, 1);
			if(firstchar.equals("/")||firstchar.equals("\\")){
				yxpath = importfilepath + yxpath;
			}else{
				yxpath = importfilepath + File.separator + yxpath;
			}
		}else{
			return null;
		}
		File file = new File(yxpath);
		currentFiletime = timeFormat.format(new Date());
		if (importlogpath == null || importlogpath.equals("")){
			importlogpath = file.getParentFile().getPath() + "/"
					+ file.getName() + "_" + currentFiletime + "/";
		}
		if (!new File(importlogpath).exists()){
			new File(importlogpath).mkdirs();
		}
		System.out.println("开始导入影像" + file.getAbsolutePath() + ":"
				+ file.isDirectory());
		if (file.isDirectory()) {
			File successfile = new File(importlogpath + "/" + file.getName()
					+ "_success_" + currentFiletime + ".txt");
			File failedfile = new File(importlogpath + "/" + file.getName()
					+ "_failed_" + currentFiletime + ".txt");
			failedfilepath = importlogpath + "/" + file.getName() + "_"
					+ currentFiletime;
			try {
				if (!successfile.exists()){
					successfile.createNewFile();
				}
				if (!failedfile.exists()){
					failedfile.createNewFile();
				}
				System.out.println("**创建日志文件**");
				successfos = new FileOutputStream(successfile);
				failedfos = new FileOutputStream(failedfile);
				successfos.write((simpleDateFormat.format(new Date()) + "开始导入：\\n").getBytes());
				failedfos.write((simpleDateFormat.format(new Date()) + "开始导入：\n").getBytes());
				System.out.println("**进入导入流程**");
				addYxByFile(file, data);
				updateTask(taskid, "2");
				successfos.write((simpleDateFormat.format(new Date()) + "导入结束\n\n").getBytes());
				failedfos.write((simpleDateFormat.format(new Date()) + "导入结束\n\n").getBytes());
				successfos.close();
				failedfos.close();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (failedfos != null) {
					try {
						failedfos.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (successfos != null) {
					try {
						successfos.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}

		}
		System.out.println("结束导入影像");
		return record;
	}

	private static boolean addYxByFile(File file, Record data) throws IOException {
		String userid = data.getStrValue("userid");
		if (file.isDirectory()) {
			// 对影像进行排序
			List<File> fileitem = Arrays.asList(file.listFiles());
			Collections.sort(fileitem, new Comparator<File>() {
				@Override
				public int compare(File o1, File o2) {
					if (o1.isDirectory() && o2.isFile())
						return -1;
					if (o1.isFile() && o2.isDirectory())
						return 1;
					return o1.getName().compareTo(o2.getName());
				}
			});
			// 遍历所有文件以及文件夹
			for (File f : fileitem) {
				if (f.isDirectory()) {
					// 遇到文件夹则递归子文件夹
					addYxByFile(f, data);
				} else {
					String filename = f.getName();
					if (filelist.contains(filename)) {
						writeFailedLog(f, "文件名称重复");
						continue;
					} else {
						filelist.add(f.getName());
					}
					// 校验文件
					String extstr = filename.substring(
							filename.lastIndexOf(".") + 1, filename.length());
					if (extstr != null && extstr.length() > 0) {

						if (extstr.toLowerCase().equals("jpeg")
								|| extstr.toLowerCase().equals("jpg")) {
						} else {
							writeFailedLog(f, "文件名类型错误");
							continue;
						}
					} else {
						writeFailedLog(f, "文件名类型错误");
						continue;
					}
					// P-MB9028-A-1.jpg
					String bh = "";
					String fw = "";
					try {
						String fss[] = filename.substring(0,
								filename.lastIndexOf(".")).split("-");
						bh = fss[1];
						fw = fss[2];

						String type = "";
						if (fw.equals("A")) {
							type = "正视图";
						} else if (fw.equals("B")) {
							type = "俯视图";
						} else if (fw.equals("C")) {
							type = "侧视图";
						} else if (fw.equals("D")) {
							type = "组件图";
						} else if (fw.equals("E")) {
							type = "局部图";
						} else if (fw.equals("K")) {
							type = "底部图";
						}
						fw = type;
					} catch (Exception e) {
						writeFailedLog(f, "文件名错误");
						continue;
					}
					int wed, hei;
					long fsize;
					try {

						InputStream fis = new FileInputStream(f);
						BufferedImage bufferedImg = ImageIO.read(fis);
						wed = bufferedImg.getWidth();
						hei = bufferedImg.getHeight();
						fis.close();
						fsize = f.length();
					} catch (Exception e) {
						writeFailedLog(f, "获取文件参数错误");
						continue;
					}
					int bmid = 0;
					long nimageid = 0;
					long lsyncid = 0;
					String img_uri = "";
					/*
					 *  bm 编目表（总账表），r_wf_entity 流程任务表，wf_order 流程定义表
					 *  c.process_id='cc2073cb426e4bce9532515abd5bb228 流程定义-编目
					 *  a.img_uri 藏品代表影像 
					*/
					/*String bmsql = "select a.id,a.img_uri from bm a,r_wf_entity b,WF_ORDER c "
							+ "where a.id=b.entity_id and b.order_id=c.id and a.bh='"
							+ bh
							+ "' and c.process_id='cc2073cb426e4bce9532515abd5bb228'";
					*/
					// 任何状态都可以上传
					String bmsql = "select a.id,a.img_uri from bm a "
							+ "where a.bh='"+ bh + "'";
					try {
						List<Record> list = getMySqlDBActor().getRowsForRecord(
								bmsql);
						if (list != null && list.size() > 0) {
							Record bm = list.get(0);
							bmid = bm.getIntValue("id");
							if(bmid>0){
								
							}else{
								writeFailedLog(f, "图片包含的登记号未录入系统");
								continue;
							}
							img_uri = bm.getStrValue("img_uri");
							nimageid = getNIMAGEMaxId();
							lsyncid = getLSYNCMaxId();
						} else {
							writeFailedLog(f, "文件名中包含藏品登记号错误");
							continue;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					Record nimage = new Record();
					nimage.add("id", nimageid);
					nimage.add("userid", userid);
					nimage.add("entity_name", "dao.bh.Bm");
					nimage.add("entity_id", bmid);
					nimage.add("title", filename);
					nimage.add("width", wed);
					nimage.add("height", hei);
					nimage.add("fsize", fsize);
					// String extstr =
					// filename.substring(filename.lastIndexOf(".")+1,filename.length());
					String uri = "[" + userid + "_image]" + nimageid + "."
							+ extstr;
					nimage.add("uri", uri);// [62_image]25672.jpg
					nimage.add("dt_create", new Date());
					nimage.add("dt_modify", new Date());
					nimage.add("type", fw);
					String nimage_sql = "INSERT INTO N_IMAGE(ID, USERID, ENTITY_NAME, ENTITY_ID, TITLE, WIDTH, HEIGHT, FSIZE, URI, DT_CREATE, DT_MODIFY, TYPE) "
							+ "VALUES ("
							+ nimageid
							+ ", "
							+ userid
							+ ", 'dao.hb.Bm', "
							+ bmid
							+ ", '"
							+ filename
							+ "', "
							+ wed
							+ ", "
							+ hei
							+ ", "
							+ fsize
							+ ", '"
							+ uri
							+ "', "
							+ "TO_DATE('"
							+ simpleDateFormat.format(new Date())
							+ "', 'SYYYY-MM-DD HH24:MI:SS'), "
							+ "TO_DATE('"
							+ simpleDateFormat.format(new Date())
							+ "', 'SYYYY-MM-DD HH24:MI:SS'), '" + fw + "')";
					Record lsync = new Record();
					lsync.add("id", lsyncid);
					lsync.add("entity", "dao.hb.NImage");
					lsync.add("entity_id", nimageid);
					lsync.add("oper", "65");
					lsync.add("dtCreate", new Date());
					lsync.add("userid", userid);
					String lsync_sql = "INSERT INTO L_SYNC(ID, ENTITY, ENTITY_ID, OPER, DT_CREATE, USERID) VALUES "
							+ "("
							+ lsyncid
							+ ", 'dao.hb.RWfEntity', "
							+ nimageid
							+ ", 65, "
							+ "TO_DATE('"
							+ simpleDateFormat.format(new Date())
							+ "', 'SYYYY-MM-DD HH24:MI:SS'), " + userid + ")";

					String fdir = sysfilepath + File.separator + userid
							+ File.separator + "image";
					String nfname = nimageid + "." + extstr;

					Record yxInfo = upload_mass(f.getAbsolutePath(), nfname,
							data, fdir);
					if (yxInfo.getStrValue("status").equals("ok")) {
						try {
							IDBActor act = getMySqlDBActor();
							String imgcountsql = "select count(id) as num from N_IMAGE where entity_Id="
									+ bmid;
							String imgcountstr = act
									.getSingleFldStrValue(imgcountsql);
							long imgcount = Long.parseLong(imgcountstr);
							imgcount = imgcount + 1;
							int i_rs = act.ExeSql(nimage_sql);
							int l_rs = act.ExeSql(lsync_sql);
							if (i_rs == 1 && l_rs == 1) {
								// 代表影像 bm
								boolean result = false;
								if (filelist.size() == 1 && isEmpty(img_uri)) {
									result = addOneYxCount_(bmid, uri, imgcount);
								} else {
									result = addOneYxCount(bmid, imgcount);
								}
								if (result) {
									String r = simpleDateFormat
											.format(new Date())
											+ ":"
											+ f.getPath() + " 导入成功\n";
									successfos.write(r.getBytes());
									f.delete();
								} else {
									writeFailedLog(f, "藏品号错误或者导入时发生错误");
								}
							} else {
								writeFailedLog(f, "附件记录添加失败");
								continue;
							}
						} catch (Exception e) {
							writeFailedLog(f, "附件记录保存失败");
							e.printStackTrace();
							continue;
						}
					} else {
						writeFailedLog(f, "分析影像出错");
					}
				}
			}
		}
		return true;
	}

	private static boolean writeFailedLog(File file, String failedmessage)
			throws IOException {
		String despath = failedfilepath + "/" + file.getParentFile().getName()
				+ "/";
		File desFile = new File(despath);
		if (!desFile.exists())
			desFile.mkdirs();
		desFile = new File(despath + file.getName());
		if (!desFile.exists())
			desFile.createNewFile();
		FileOutputStream out = new FileOutputStream(desFile);
		FileInputStream in = new FileInputStream(file);

		byte[] buffer = new byte[1024];
		int byteread = 0;
		while ((byteread = in.read(buffer)) != -1) {
			out.write(buffer, 0, byteread);
		}
		out.close();
		in.close();
		String r = "失败：" + simpleDateFormat.format(new Date()) + ":"
				+ file.getPath() + " \n";
		r += "  失败原因：" + failedmessage + "\n";
		failedfos.write(r.getBytes());
		return true;
	}

	/**
	 * addOneYxCount(设置影像数量)
	 * 
	 * @author wangli
	 * @param bmid
	 * @param imgcount
	 * @return
	 */
	private static boolean addOneYxCount(int bmid, long imgcount) {
		String updateSql = "update BM set img_sum=" + imgcount + " where id="
				+ bmid;
		try {
			int rs = getMySqlDBActor().ExeSql(updateSql);
			if (rs == 1) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * addOneYxCount_(设置代表影像和影像数量)
	 * 
	 * @author wangli
	 * @param bmid
	 * @param uri
	 * @param imgcount
	 * @return
	 */
	private static boolean addOneYxCount_(int bmid, String uri, long imgcount) {
		String updateSql = "update BM set img_uri='" + uri + "',img_sum="
				+ imgcount + " where id=" + bmid;
		try {
			int rs = getMySqlDBActor().ExeSql(updateSql);
			if (rs == 1) {
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private static boolean isEmpty(String str) {
		if (str != null && str.length() > 0) {
			return false;
		} else {
			return true;
		}
	}
	
	public static void main(String[] args) {
		String path = "C:\\daxtfile\\mbftp\\1";
		File f = new File(path);
		List<File> fileitem = Arrays.asList(f.listFiles());
		Collections.sort(fileitem, new Comparator<File>() {
			@Override
			public int compare(File o1, File o2) {
				if (o1.isDirectory() && o2.isFile())
					return -1;
				if (o1.isFile() && o2.isDirectory())
					return 1;
				return o1.getName().compareTo(o2.getName());
			}
		});
		for(File ff:fileitem){
			System.out.println(ff.getName());
			System.out.println(ff.getPath());
		}
	}

}